//
//  SearchEngine.m
//  pkphotomap
//
//  Created by Ed Mancebo on 3/24/11.
//  Copyright 2011 Personal. All rights reserved.
//

#import "SearchEngine.h"
#import "RequestIdGenerator.h"
#import "MapViewController.h"
#import "PKImage.h"
#import "SearchWorker.h"
#import "SearchRequest.h"
#import "SearchOperation.h"

#include <libkern/OSAtomic.h>

@implementation SearchEngine

static int ROWS = 2;
static int COLS = 2;

static NSOperationQueue *queue;
+ (void)initialize
{
    if(self == [SearchEngine class])
    {
        queue = [[NSOperationQueue alloc] init];
		[queue setMaxConcurrentOperationCount:(ROWS*COLS)];
    }
}

// The search query is partitioned into geographical regions to ensure that we get results
// from all areas of the map
- (void) partitionAndSubmitSearch:(SearchRequest*)request {
	
	// remove off screen annotations and images
	MapViewController *mapViewController = [MapViewController getInstance];
	[mapViewController removeImagesOutsideMinCoord:request.minCoord maxCoord:request.maxCoord];
	
	// get IDs of images remaining in the visible region
	
	NSDictionary *curImageIdSet = [mapViewController getImageIdSet];
	
	double dy = (request.maxCoord.latitude - request.minCoord.latitude) / ROWS;
	double dx = (request.maxCoord.longitude - request.minCoord.longitude) / COLS;
	
	for (int row=0; row < ROWS; ++row) {
		for (int col=0; col < COLS; ++col) {
			
			// construct search request for this partition
			SearchRequest *psr = [[SearchRequest alloc] init];
			psr.rid = request.rid;
			CLLocationCoordinate2D minCoord;
			CLLocationCoordinate2D maxCoord;
			minCoord.latitude = request.minCoord.latitude + dy*row;
			minCoord.longitude = request.minCoord.longitude + dx*col;
			maxCoord.latitude = request.minCoord.latitude + dy*(row+1);
			maxCoord.longitude = request.minCoord.longitude + dx*(col+1);
			psr.minCoord = minCoord;
			psr.maxCoord = maxCoord;
			
			/*
			static volatile int ccount = 0;
			
			dispatch_async(dispatch_get_global_queue(0, 0), ^{
				OSAtomicIncrement32(&ccount);
				NSLog(@"ccount = %d", ccount);
				SearchWorker *worker = [[SearchWorker alloc] init];
				[worker search:psr curImages:curImageIdSet];
				[worker release];
				OSAtomicDecrement32(&ccount);
				NSLog(@"ccount = %d", ccount);
			});
			 */
			
			// ---------------------
			// new dispatch
			psr.curImageIds = curImageIdSet;
			SearchOperation *op = [[SearchOperation alloc] initWithRequest:psr];
			[queue addOperation:op];
			[op release];
			// ---------------------
			[psr release];
		}
	}	
}

@end
